/*
 * Copyright Redis Ltd. 2018 - present
 * Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
 * the Server Side Public License v1 (SSPLv1).
 */

#pragma once

#include "op.h"
#include "op_argument.h"
#include "../execution_plan.h"
#include "shared/update_functions.h"
#include "../../resultset/resultset_statistics.h"

/* The Merge operation accepts exactly one path in the query and attempts to match it.
 * If the path is not found, it will be created, making new instances of every path variable
 * not bound in an earlier clause in the query. */
typedef struct {
	OpBase op;                               // Base op.
	OpBase *match_stream;                    // Child stream that attempts to resolve the pattern.
	OpBase *create_stream;                   // Child stream that will create the pattern if not found.
	OpBase *bound_variable_stream;           // Optional child stream to resolve previously bound variables.
	Argument *match_argument_tap;            // Argument tap to populate Match stream with bound variables.
	Argument *create_argument_tap;           // Argument tap to populate Create stream with bound variables.
	Record *input_records;                   // Records generated by the bound variable stream.
	Record *output_records;                  // Records to be emitted by this operation.
	rax *on_match;                           // Updates to be performed on a successful match.
	rax *on_create;                          // Updates to be performed on creation.
	raxIterator on_match_it;                 // Iterator for traversing ON MATCH update contexts.
	raxIterator on_create_it;                // Iterator for traversing ON CREATE update contexts.
	dict *node_pending_updates;              // Pending updates to apply, generated 
	dict *edge_pending_updates;              // Pending updates to apply, generated 
} OpMerge;

OpBase *NewMergeOp(const ExecutionPlan *plan, rax *on_match, rax *on_create);

